<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <!--  <img width="300" alt="Angular Logo" src="">-->
</div>
<ul>
  <li *ngFor="let item of items">{{item}}</li>
</ul>
<app-child [item]="msg" (newItemEvent)="addItem($event)"></app-child>
<hr>
<p style="color: red">绑定事件</p>
<button (click)="onSave($event,'111')">Save</button>

<hr>
<p style="color: red">管道：格式化数据</p>
<p>The hero's birthday is {{birthday}} -- {{ birthday | date }}</p>
<p style="color: red">管道传参：</p>
<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
<p style="color: red">动态切换管道的参数：</p>
<p>The hero's birthday is {{ birthday | date: format }} </p>
<button (click)="toggleFormat()">Toggle Format</button>
<p style="color: red">通过串联管道应用两种格式：</p>
<p>
  The chained hero's birthday is
  {{ birthday | date | uppercase}}
</p>
<p>
  The chained hero's birthday is
  {{ birthday | date:'fullDate' | uppercase}}
</p>
<p style="color: red">使用自定义管道</p>
<h2>Power Booster</h2>
<p>Super power boost: {{2 | exponentialStrength: 10}}</p>
<p style="color: red">通过管道中的数据绑定来检测变更</p>
<h2>Power Boost Calculator</h2>
<div>Normal power: <input [(ngModel)]="power"></div>
<div>Boost factor: <input [(ngModel)]="factor"></div>
<p>
  Super Hero Power: {{power | exponentialStrength: factor}}
</p>
<p style="color: red">
  变更检测的工作原理：
</p>
New hero:
<input type="text" #box (keyup.enter)="addHero(box.value); box.value=''" placeholder="hero name">
<p>{{box.value}}</p>
<button (click)="reset()">Reset</button>
<div *ngFor="let hero of heroes">
  {{hero.name}}
</div>

<p style="color: red">模板变量：</p>
<input #phone placeholder="phone number" />
<button (click)="callPhone(phone.value)">Call</button>

<p style="color: red">将 NgForm 与模板变量一起使用</p>
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
  <label for="name">Name <input class="form-control" name="name" ngModel required />
  </label>
  <button type="submit">Submit</button>
</form>
<div [hidden]="!itemForm.form.valid">
  <p>{{ submitMessage }}</p>
</div>

<p style="color: red">访问 < ng-template> 的模板变量</p>
<ng-template #ref3></ng-template>
<button (click)="log(ref3)">Log type of #ref</button>

<hr>
<h2>内置属性型指令</h2>
<p style="color: red">内置属性型指令：NgClass，用 ngClass 同时添加或删除几个 CSS 类。</p>
<div [ngClass]="isSpecial ? 'special' : ''">This div is special</div>
<div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special.</div>
<button (click)="changeClass('saveable')">修改样式</button>

<p style="color: red">
  内置属性型指令：NgStyle，使用 NgStyle 根据组件的状态同时动态设置多个内联样式。
</p>
<!--有些情况下，要考虑使用样式绑定来设置单个样式值，而不使用 NgStyle。-->
<div [style.font-size]="isSpecial ? '40px' : '12px'">
  This div is x-large or smaller.
</div>
<!--但是，如果要同时设置多个内联样式，请使用 NgStyle 指令。-->
<div [ngStyle]="currentStyles">
  This div is initially italic, normal weight, and extra large (24px).
</div>

<p style="color: red">[(ngModel)] ：双向绑定</p>
<!--要想在双向数据绑定中使用 ngModel 指令，必须先导入 FormsModule 并将其添加到 NgModule 的 imports 列表中。-->
<label for="example-ngModel">[(ngModel)]:</label>
<input [(ngModel)]="currentItem.name" id="example-ngModel">
<p>{{currentItem.name}}</p>
<!--通过分别绑定到 <input> 元素的 value 属性和 input 事件，可以达到同样的效果：-->
<input [value]="currentItem.name" (input)="currentItem.name=$event.target.value" id="without">
<br>
<!--ngModel 输入属性会设置该元素的值，并通过 ngModelChange 的输出属性来监听元素值的变化。-->
<label for="example-change">(ngModelChange)="...name=$event":</label>
<input [ngModel]="currentItem.name" (ngModelChange)="currentItem.name = $event" id="example-change">
<!--此 [(ngModel)] 语法只能设置数据绑定属性。如果你要做得更多，可以编写扩展表单。例如，下面的代码将 <input> 值更改为大写：-->
<div>
  <input [ngModel]="currentItem.name" (ngModelChange)="setUppercaseName($event)" id="example-uppercase">
</div>

<hr>
<h2>内置结构型指令</h2>
<!--结构型指令的职责是 HTML 布局。 它们塑造或重塑 DOM 的结构，这通常是通过添加、移除和操纵它们所附加到的宿主元素来实现的。-->
<h3>NgIf</h3>
<p *ngIf="isActive">你好啊，李银河</p>
<button (click)="changeState()">切换状态</button>

<!--隐藏元素与使用 NgIf 删除元素不同。为了进行比较，下面的范例演示如何使用类或样式绑定来控制元素的可见性。-->
<div [class.hidden]="!isSpecial">Show with class</div>
<div [class.hidden]="isSpecial">Hide with class</div>

<div [style.display]="isSpecial ? 'block' : 'none'">Show with style</div>
<div [style.display]="isSpecial ? 'none'  : 'block'">Hide with style</div>


<div *ngIf="currentCustomer">Hello, {{currentCustomer.name}}</div>
<div *ngIf="nullCustomer">Hello, <span>{{nullCustomer}}</span></div>
<!--<form #heroForm (ngSubmit)="onSubmit(heroForm)"> ... </form>-->

<h3>NgFor</h3>
<div *ngFor="let item of items2; let i=index">{{i + 1}} - {{item.name}}</div>

<div *ngFor="let item of items2; trackBy: trackByItems">
  ({{item.id}}) {{item.name}}
</div>

<h3>NgSwitch 指令</h3>

<hr>
<h3>创建一个简单的属性型指令</h3>
<h2>Pick a highlight color</h2>
<div>
  <input type="radio" name="colors" (click)="color='lightgreen'">Green
  <input type="radio" name="colors" (click)="color='yellow'">Yellow
  <input type="radio" name="colors" (click)="color='cyan'">Cyan
</div>
<p ngNonBindable [appHighlight]="color" defaultColor="violet">Highlight me! {{1 + 1}}</p>

<!--使用由模板引擎原生支持的 ngNonBindable 伪指令，可以让 Angular 不对模板中的表达式进行求值。例如：-->
<p ngNonBindable>This should not evaluate: {{ 1 + 1 }}</p>

<h3>结构型指令</h3>
<p>结构型指令的职责是 HTML 布局。 它们塑造或重塑 DOM 的结构，比如添加、移除或维护这些元素。</p>
<h3>
  < ng-template>元素
</h3>
<p>
  < ng-template>是一个 Angular 元素，用来渲染 HTML。 它永远不会直接显示出来。 事实上，在渲染视图之前，Angular 会把 < ng-template> 及其内容替换为一个注释。
      如果没有使用结构型指令，而仅仅把一些别的元素包装进 < ng-template> 中，那些元素就是不可见的。
</p>
<h3>使用< ng-container>把一些兄弟元素归为一组</h3>
<p>Angular 的 < ng-container> 是一个分组元素，但它不会污染样式或元素布局，因为 Angular 压根不会把它放进 DOM 中。</p>
<h3>写一个结构型指令</h3>
<p *appUnless="condition" class="unless a">
  (A) This paragraph is displayed because the condition is false.
</p>

<p *appUnless="!condition" class="unless b">
  (B) Although the condition is true,
  this paragraph is displayed because appUnless is set to false.
</p>
<hr>

<h1>Angular Router App</h1>
<nav>
  <ul>
    <!--动态路由传值-->
    <li><a routerLink="/first-component/3" routerLinkActive="active">First Component</a></li>
    <!--params传参-->
    <li>
      <a routerLink="/second-component" [queryParams]="{name: '小笑残虹'}" routerLinkActive="active">
        Second Component
      </a>
    </li>
    <li>
      <a routerLink="/home" routerLinkActive="active">
        Home 页面
      </a>
    </li>
  </ul>
</nav>


<!-- js跳转路由 -->
<button (click)="goHome()">js跳转路由</button>

<!-- js动态路由跳转 -->
<button (click)="goToPath()">js动态路由跳转</button>

<button (click)="queryRoute()">js跳转路由query传参</button>

<router-outlet></router-outlet>

<h3>获取路由信息</h3>
<hr>
<h3>表单</h3>
<app-name-editor></app-name-editor>
<h2>表单组、创建嵌套的表单组：FormGroup</h2>
<app-profile-editor></app-profile-editor>

<h2>更新部分数据模型</h2>
<p>有两种更新模型值的方式：</p>
<ul>
  <li>使用 setValue() 方法来为单个控件设置新值。 setValue() 方法会严格遵循表单组的结构，并整体性替换控件的值。</li>
  <li>使用 patchValue() 方法可以用对象中所定义的任何属性为表单模型进行替换。</li>
  <li>setValue() 方法的严格检查可以帮助你捕获复杂表单嵌套中的错误，而 patchValue() 在遇到那些错误时可能会默默的失败。</li>
</ul>

<h2>验证表单输入</h2>

<h2>创建动态表单</h2>
<p>
  FormArray 是 FormGroup 之外的另一个选择，用于管理任意数量的匿名控件。像 FormGroup 实例一样，你也可以往 FormArray 中动态插入和移除控件，并且 FormArray
  实例的值和验证状态也是根据它的子控件计算得来的。
  不过，你不需要为每个控件定义一个名字作为 key，因此，如果你事先不知道子控件的数量，这就是一个很好的选择。
</p>
<p>要定义一个动态表单，请执行以下步骤。</p>
<ul>
  <li>导入 FormArray 类。</li>
  <li>定义一个 FormArray 控件。</li>
  <li>使用 getter 方法访问 FormArray 控件。</li>
  <li>在模板中显示这个表单数组。</li>
</ul>

<h2>验证表单输入</h2>

<hr>

<!-- 表单 -->
<app-hello-form></app-hello-form>

<hr>
<h2>HTTP客户端</h2>
<p>要想使用 HttpClient，就要先导入 Angular 的 HttpClientModule。大多数应用都会在根模块 AppModule 中导入它。</p>
<app-news></app-news>
